﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Windows.Forms;
using System.IO;

using AtletIS.Shared.Entities;
using AtletIS.Shared.Data;
using AtletIS.Shared.Data.aDbDataSetTableAdapters;
using AtletIS.Shared.WpfControls;
using System.Drawing;

namespace AtletIS.Shared.Helpers
{
    public static class DisciplineListHelper
    {
        private static DisciplineListTableAdapter taDisciplineList = new DisciplineListTableAdapter();
        private static PerformancesTableAdapter taPerformances = new PerformancesTableAdapter();
        
        /// <summary>
        ///  Konvertuje DataRow na DisciplineListEntity
        /// </summary>
        public static DisciplineListEntity ConvertToEntity(DataRow drDisciplineList)
        {
            DisciplineListEntity disc = new DisciplineListEntity();
            
            disc.ID = Convert.ToInt32(drDisciplineList["ID"]);
            disc.Name = Convert.ToString(drDisciplineList["Name"]);

            disc.AutoOrder = Convert.ToInt32(drDisciplineList["AutoOrder"]);
            disc.Order = Convert.ToInt32(drDisciplineList["Order"]);
            disc.SecondaryOrder = Convert.ToInt32(drDisciplineList["SecondaryOrder"]);

            disc.ParentId = Convert.ToInt32(drDisciplineList["ParentId"]);
            disc.CompetitionId = Convert.ToInt32(drDisciplineList["CompetitionId"]);
            disc.DisciplineId = Convert.ToInt32(drDisciplineList["DisciplineId"]);
            disc.CategoryId = Convert.ToInt32(drDisciplineList["CategoryId"]);
            disc.StartTime = Convert.ToDateTime(drDisciplineList["StartTime"]);
            
            if (drDisciplineList["RealStartTime"] != DBNull.Value)
                disc.RealStartTime = Convert.ToDateTime(drDisciplineList["RealStartTime"]);
            
            if (drDisciplineList["RealEndTime"] != DBNull.Value)
                disc.RealEndTime = Convert.ToDateTime(drDisciplineList["RealEndTime"]);

            if (drDisciplineList["Wind"] != DBNull.Value)
                disc.Wind = Convert.ToDouble(drDisciplineList["Wind"]);
            
            disc.Status = Convert.ToInt32(drDisciplineList["Status"]);
            disc.DisciplineCode = Convert.ToInt32(drDisciplineList["DisciplineCode"]);
            disc.ResultCode = Convert.ToInt32(drDisciplineList["ResultCode"]);
            disc.Params = Convert.ToString(drDisciplineList["Params"]);
            disc.Description = drDisciplineList["Description"].ToString();
            disc.MeasurementId = Convert.ToInt32(drDisciplineList["MeasurementId"]);

            return disc;
        }

        public static DisciplineListEntity GetActiveDiscipline(int id)
        {
            return ConvertToEntity(DatabaseHelper.GetDisciplineListById(id).Rows[0]);
        }

        /// <summary>
        ///  Naplní TreeView so zoznamom disciplín pre ActiveCompetition
        /// </summary>
        public static void FillTreeView(TreeView tvDisciplines)
        {
            DataTable dtParents, dtAllChildren; 
            DataRow[] dtChildren, dtGrandChidlren;
            string parentId, childId, grandChildId;

            tvDisciplines.DrawMode = TreeViewDrawMode.OwnerDrawText;
            tvDisciplines.HideSelection = false;
            tvDisciplines.DrawNode += (sender, e) =>
            {
                if (e.Node == null) return;

                // if treeview's HideSelection property is "True", 
                // this will always returns "False" on unfocused treeview
                var selected = (e.State & TreeNodeStates.Selected) == TreeNodeStates.Selected;
                var unfocused = !e.Node.TreeView.Focused;

                // we need to do owner drawing only on a selected node
                // and when the treeview is unfocused, else let the OS do it for us
                if (selected && unfocused)
                {
                    var font = e.Node.NodeFont ?? e.Node.TreeView.Font;
                    e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds);
                    TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, SystemColors.HighlightText, TextFormatFlags.GlyphOverhangPadding);
                }
                else
                {
                    e.DrawDefault = true;
                }
            };

            tvDisciplines.Nodes.Clear();

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                dtParents = DatabaseHelper.GetDisciplineListByCompetitionIdActive(Globals.ActiveCompetition.ID); // taDisciplineList.GetByCompetitionId(Globals.ActiveCompetition.ID);
                dtAllChildren = DatabaseHelper.GetDisciplineListByCompetitionIdChildrenActive(Globals.ActiveCompetition.ID); // taDisciplineList.GetByCompetitionIdChildren(Globals.ActiveCompetition.ID);
                
                foreach (DataRow dr in dtParents.Select(null, "Order"))
                {
                    parentId = dr["ID"].ToString();
                    tvDisciplines.Nodes.Add(parentId, dr["Name"].ToString(), Convert.ToInt32(dr["Status"]) - 1);

                    dtChildren = dtAllChildren.Select("ParentID = " + parentId, "SecondaryOrder");
                    foreach (DataRow drChild in dtChildren)
                    {
                        childId = drChild["ID"].ToString();
                        tvDisciplines.Nodes[parentId].Nodes.Add(childId, Convert.ToString(drChild["Name"]), Convert.ToInt32(drChild["Status"]) - 1);

                        dtGrandChidlren = dtAllChildren.Select("ParentId = " + childId, "SecondaryOrder"); 
                        foreach (DataRow drGrandChild in dtGrandChidlren)
                        {
                            grandChildId = drGrandChild["ID"].ToString();
                            tvDisciplines.Nodes[parentId].Nodes[childId].Nodes.Add(grandChildId, Convert.ToString(drGrandChild["Name"]), Convert.ToInt32(drGrandChild["Status"]) - 1);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        public static void FillListBoxWPF(System.Windows.Controls.ListBox lbDisciplines)
        {
            DataTable dtParents, dtAllChildren;
            string parentId, childId, grandChildId;

            lbDisciplines.Items.Clear();

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                dtParents = DatabaseHelper.GetDisciplineListByCompetitionIdActive(Globals.ActiveCompetition.ID); // taDisciplineList.GetByCompetitionId(Globals.ActiveCompetition.ID);
                dtAllChildren = DatabaseHelper.GetDisciplineListByCompetitionIdChildrenActive(Globals.ActiveCompetition.ID); // taDisciplineList.GetByCompetitionIdChildren(Globals.ActiveCompetition.ID);

                foreach (DataRow dr in dtParents.Select(null, "Order"))
                {
                    parentId = Convert.ToString(dr["ID"]);
                    lbDisciplines.Items.Add(new DisciplineListBox1(DisciplineListHelper.ConvertToEntity(dr)));

                    foreach (DataRow drChild in dtAllChildren.Select("ParentId = " + parentId, "SecondaryOrder"))
                    {
                        childId = Convert.ToString(drChild["ID"]);
                        lbDisciplines.Items.Add(new DisciplineListBox2(DisciplineListHelper.ConvertToEntity(drChild)));

                        foreach (DataRow drGrandChild in dtAllChildren.Select("ParentId = " + childId, "SecondaryOrder"))
                        {
                            grandChildId = Convert.ToString(drGrandChild["ID"]);
                            lbDisciplines.Items.Add(new DisciplineListBox3(DisciplineListHelper.ConvertToEntity(drGrandChild)));

                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Načítanie zoznamu disciplín", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        /// <summary>
        ///  Vygeneruje HTML zoznam disciplín
        /// </summary>
        public static void Export(CompetitionEntity competition)
        {
            DisciplineListTableAdapter taDisciplineList = new DisciplineListTableAdapter();
            DataTable dtParents, dtChildren, dtGrandChidlren;
            string parentId, childId;
            
            string path = "Ext\\disc_list.html";
            StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8);

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                Helpers.HtmlHelper.PrintHtmlHead(sw, "Zoznam disciplín");
                sw.WriteLine("<body>");
                sw.WriteLine();
                sw.WriteLine("<!-- HEADER -->");
                sw.WriteLine("<div id=\"header\">");
                sw.WriteLine("  <img src=\"header.png\" alt=\"Header\"/>");
                sw.WriteLine("  <hr>");
                sw.WriteLine("  <h1>" + competition.Name + "</h1>");
                sw.WriteLine("  <b>Vygenerované " + DateTime.Now.ToShortDateString() + " o " + DateTime.Now.ToShortTimeString() + "</b>");
                sw.WriteLine("</div>");

                dtParents = DatabaseHelper.GetDisciplineListByCompetitionIdActive(competition.ID); 
                // taDisciplineList.GetByCompetitionId(competition.ID);

                sw.WriteLine("<h3>Zoznam disciplín</h3>");
                sw.WriteLine("<table class=\"extra\">");
                sw.WriteLine("<tr height=\"30\" bgcolor=\"#D8D8D8\">");
                sw.WriteLine("  <th width=\"120\">Štart</th>");
                sw.WriteLine("  <th width=\"40\">ID</th>");
                sw.WriteLine("  <th width=\"600\">Názov</th>");
                sw.WriteLine("</tr>");

                int rowCount = 1;
                foreach (DataRow dr in dtParents.Select(null, "Order"))
                {
                    parentId = Convert.ToString(dr["ID"]);

                    if (rowCount % 2 == 1)
                        sw.WriteLine("<tr>");
                    else
                        sw.WriteLine("<tr bgcolor=\"#CFECEC\">");

                    sw.WriteLine("  <td align=\"center\">" + Convert.ToDateTime(dr["StartTime"]).ToString("dd.MM.yyyy HH:mm") + "</td>");
                    sw.WriteLine("  <td align=\"center\">(" + dr["ID"].ToString() + ")</td>");
                    sw.WriteLine("  <td>" + dr["Name"].ToString() + "</td>");
                    sw.WriteLine("</tr>");
                    rowCount += 1;

                    dtChildren = DatabaseHelper.GetDisciplineListByParentIdActive(Convert.ToInt32(parentId)); // taDisciplineList.GetByParentId(Convert.ToInt32(parentId));
                    foreach (DataRow drChild in dtChildren.Rows)
                    {
                        childId = Convert.ToString(drChild["ID"]);

                        if (rowCount % 2 == 1)
                            sw.WriteLine("<tr>");
                        else
                            sw.WriteLine("<tr bgcolor=\"#CFECEC\">");

                        sw.WriteLine("  <td></td>");
                        sw.WriteLine("  <td align=\"center\">" + drChild["ID"].ToString() + "</td>");
                        sw.WriteLine("  <td> + " + drChild["Name"].ToString() + "</td>");
                        sw.WriteLine("</tr>");
                        rowCount += 1;

                        dtGrandChidlren = DatabaseHelper.GetDisciplineListByParentIdActive(Convert.ToInt32(childId)); // taDisciplineList.GetByParentId(Convert.ToInt32(childId));
                        foreach (DataRow drGrandChild in dtGrandChidlren.Rows)
                        {

                            if (rowCount % 2 == 1)
                                sw.WriteLine("<tr>");
                            else
                                sw.WriteLine("<tr bgcolor=\"#CFECEC\">");

                            sw.WriteLine("  <td></td>");
                            sw.WriteLine("  <td align=\"center\">" + drGrandChild["ID"].ToString() + "</td>");
                            sw.WriteLine("  <td> + + " + drGrandChild["Name"].ToString() + "</td>");
                            sw.WriteLine("</tr>");
                            rowCount += 1;
                        }
                    }
                }
                sw.WriteLine("</table>");

                HtmlHelper.PrintFooter(sw);
                sw.WriteLine("</body>");
                sw.WriteLine("</html>");

                System.Diagnostics.Process.Start(path);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Generovanie zoznamu disciplín", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                sw.Close();
                sw.Dispose();
                Cursor.Current = Cursors.Default;
            }
        }

        /// <summary>
        ///  Zruší rozdelenie.
        /// </summary>
        public static void CancelSplit(TreeNode tnHeader)
        {
            int nMainDisciplineListId = Convert.ToInt32(tnHeader.Parent.Name);
            int nHeaderId = Convert.ToInt32(tnHeader.Name);

            DataTable dtHeader = DatabaseHelper.GetDisciplineListById(nHeaderId);
            if (dtHeader.Rows.Count > 0)
            {
                if (Convert.ToInt32(dtHeader.Rows[0]["SecondaryOrder"]) != 1)
                {
                    MessageBox.Show("Postupovú disciplínu nie je možné zrušiť", "Zrušiť rozdelenie", 
                        MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else
                {
                    try
                    {
                        aDbDataSet.DisciplineListDataTable dtChildren = DatabaseHelper
                            .GetDisciplineListByParentIdActive(nHeaderId);
                        
                        for (int i = dtChildren.Rows.Count - 1; i >= 0; i--)
                        {
                            // Presunie pretekarov naspat do hlavnej discipliny
                            aDbDataSet.PerformancesDataTable dtPerformances = DatabaseHelper
                                .GetPerformancesByDisciplineListId(Convert.ToInt32(dtChildren.Rows[i]["ID"])); 
                            
                            foreach (DataRow drPerf in dtPerformances.Rows)
                            {
                                drPerf["DisciplineListId"] = nMainDisciplineListId;
                                drPerf["Lane"] = 0;
                            }
                            taPerformances.Update(dtPerformances);

                            // Zmaze disciplinu
                            dtChildren.Rows[i]["Active"] = 0;
                            dtChildren.Rows[i]["Modified"] = DateTime.Now;
                        }

                        // Zmaze discipliny
                        taDisciplineList.Update(dtChildren);

                        // Zmaze hlavicku
                        dtHeader.Rows[0]["Active"] = 0;
                        dtHeader.Rows[0]["Modified"] = DateTime.Now;

                        taDisciplineList.Update(dtHeader.Rows[0]);

                        MessageBox.Show("Rozdelenie bolo zrušené!", "Zrušiť rozdelenie", 
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), "Zrušiť rozdelenie", 
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                
            }
        }

        /// <summary>
        ///  Zmazať postupové kolo.
        /// </summary>
        public static void CancelAdvance(TreeNode tnHeader)
        {
            int nHeaderId = Convert.ToInt32(tnHeader.Name);

            DataTable dtHeader = DatabaseHelper.GetDisciplineListById(nHeaderId);
            if (dtHeader.Rows.Count > 0)
            {
                if (Convert.ToInt32(dtHeader.Rows[0]["SecondaryOrder"]) == 1)
                {
                    MessageBox.Show("Prvotné rozdelenie nie je možné zmazať.", "Zmazať postup", 
                        MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else
                {
                    try
                    {
                        aDbDataSet.DisciplineListDataTable dtChildren = DatabaseHelper
                            .GetDisciplineListByParentIdActive(nHeaderId);
                        
                        for (int i = dtChildren.Rows.Count - 1; i >= 0; i--)
                        {
                            // Presunie pretekarov naspat do hlavnej discipliny
                            aDbDataSet.PerformancesDataTable dtPerformances = DatabaseHelper
                                .GetPerformancesByDisciplineListId(Convert.ToInt32(dtChildren.Rows[i]["ID"]));
                            
                            foreach (DataRow drPerf in dtPerformances.Rows)
                            {
                                drPerf["Active"] = 0;
                                drPerf["Modified"] = DateTime.Now;
                            }
                            taPerformances.Update(dtPerformances);

                            // Zmaze disciplinu
                            dtChildren.Rows[i]["Active"] = 0;
                            dtChildren.Rows[i]["Modified"] = DateTime.Now;
                        }

                        // Zmaze discipliny
                        taDisciplineList.Update(dtChildren);

                        // Zmaze hlavicku
                        dtHeader.Rows[0]["Active"] = 0;
                        dtHeader.Rows[0]["Modified"] = DateTime.Now;

                        taDisciplineList.Update(dtHeader.Rows[0]);

                        MessageBox.Show("Postupové kolo bolo zmazané!", "Zmazať postupové kolo", 
                            MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString(), "Zmazať postupové kolo", 
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                
            }
        }

        public static void CopyValues(DataRow drFrom, ref aDbDataSet.DisciplineListRow drTo, string name, int secondaryOrder, bool isFinal, int parentId = 0)
        {
            drTo.Name = name;
            
            drTo.ParentId = (parentId > 0) ? parentId : Convert.ToInt32(drFrom["ID"]);
            drTo.CompetitionId = Convert.ToInt32(drFrom["CompetitionId"]);
            drTo.DisciplineId = Convert.ToInt32(drFrom["DisciplineId"]);
            drTo.CategoryId = Convert.ToInt32(drFrom["CategoryId"]);
            
            drTo.Order = Convert.ToInt32(drFrom["Order"]);
            drTo.SecondaryOrder = secondaryOrder;
            
            drTo.Status = 1;
            drTo.MeasurementId = 1;
            drTo.Description = string.Empty;
            drTo.Params = (isFinal) ? "F" : string.Empty;
            
            drTo.StartTime = Convert.ToDateTime(drFrom["StartTime"]);
            drTo.SetRealStartTimeNull();
            drTo.SetRealEndTimeNull();

            drTo.SetWindNull();
            drTo.SetActivePerformanceIdNull();
            drTo.SetActivePerformanceHeaderNull();

            drTo.ShowSplits = true;

            drTo.Active = true;
            drTo.Visible = true;
            drTo.Sync = false;
            drTo.WebId = 0;
            drTo.Modified = DateTime.Now;
        }

    }
}
